package com.zcxy.fast.config;

import com.fasterxml.classmate.TypeResolver;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.schema.AlternateTypeRuleConvention;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.schema.AlternateTypeRules.newRule;

/**
 * api页面 /swagger-ui.html
 *
 * @author zcc
 * @date 2019-11-23
 */
@Configuration
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "fast.swagger",value = {"enable"},havingValue = "true")
public class SwaggerConfig implements WebMvcConfigurer {

    @Autowired
    private SwaggerProperties swaggerProperties;

    private   String tokenHeader = "Authorization";

    private   String tokenStartWith = "Bearer ";

    private   String basePackage = "com.zcxy";

    private   String title = " 接口文档";

    private   String version  = "1.0";

   @Bean
    EnableSwagger enableSwagger()
    {
        return new EnableSwagger();
    }
    @Bean
    @SuppressWarnings("all")
    public Docket createRestApi() {
        ParameterBuilder ticketPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();




        ticketPar.name(getTokenHeader()).description("token")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .defaultValue(getTokenStartWith() + " ")
                .required(true)
                .build();
        pars.add(ticketPar.build());


        return new Docket(DocumentationType.SWAGGER_2).groupName("FASTJAVA").apiInfo(apiInfo()).select()
                // 此包路径下的类，才生成接口文档
                .apis(RequestHandlerSelectors.basePackage(getBasePackage())).apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()).build().globalOperationParameters(pars);
    }

    /**
     * 方案一： 默认访问根路径跳转 doc.html页面 （swagger文档页面） 方案二： 访问根路径改成跳转 index.html页面 （简化部署方案： 可以把前端打包直接放到项目的 webapp，上面的配置）
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("doc.html");
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(getTitle())
                .version(getVersion())
                .build();
    }


    public String getTokenHeader() {
        return StringUtils.isEmpty(swaggerProperties.getTokenHeader())?tokenHeader:swaggerProperties.getTokenHeader();
    }

    public String getTokenStartWith() {
        return StringUtils.isEmpty(swaggerProperties.getTokenStartWith())?tokenStartWith:swaggerProperties.getTokenStartWith();
    }

    public String getBasePackage() {
        return StringUtils.isEmpty(swaggerProperties.getBasePackage())?basePackage:swaggerProperties.getBasePackage();
    }

    public String getTitle() {
        return StringUtils.isEmpty(swaggerProperties.getTitle())?title:swaggerProperties.getTitle();
    }

    public String getVersion() {
        return StringUtils.isEmpty(swaggerProperties.getVersion())?version:swaggerProperties.getVersion();
    }
}

/**
 * 将Pageable转换展示在swagger中
 */
@Configuration
@ConditionalOnProperty(prefix = "fast.swagger",value = {"enable"},havingValue = "true")
class SwaggerDataConfig {

    @Bean
    public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
        return new AlternateTypeRuleConvention() {
            @Override
            public int getOrder() {
                return Ordered.HIGHEST_PRECEDENCE;
            }

            @Override
            public List<AlternateTypeRule> rules() {
                return newArrayList(newRule(resolver.resolve(SpringDataWebProperties.Pageable.class), resolver.resolve(Page.class)));
            }
        };
    }

    @ApiModel
    @Data
    private static class Page {
        @ApiModelProperty("页码 (0..N)")
        private Integer page;

        @ApiModelProperty("每页显示的数目")
        private Integer size;

        @ApiModelProperty("以下列格式排序标准：property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件：如：id,asc")
        private List<String> sort;
    }


}
